unit fPickObject;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  System.Math,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls,

  GLS.Cadencer,
  GLS.Scene,
  GLS.Objects,
  GLS.GeomObjects,
  GLS.Coordinates,
  GLS.SceneViewer,
  GLS.BaseClasses;

type
  TFormObjects = class(TForm)
    GLScene1: TGLScene;
    GLSceneViewer1: TGLSceneViewer;
    GLCube1: TGLCube;
    GLCone1: TGLCone;
    GLSphere1: TGLSphere;
    GLCamera1: TGLCamera;
    GLLightSource1: TGLLightSource;
    GLPlane1: TGLPlane;
    dcTarget: TGLDummyCube;
    GLCadencer1: TGLCadencer;
    oldTarget: TGLDummyCube;
    procedure GLSceneViewer1MouseDown(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure GLCadencer1Progress(Sender: TObject; const deltaTime,
      newTime: Double);
    procedure FormCreate(Sender: TObject);
  private
    FValue: Single;
    FNewTarget: TGLBaseSceneObject;
    StartTime: Single;
    AnimationTime: Single;
  public
    function GetCurveValue(Position: Single): Single;
  end;

var
  FormObjects: TFormObjects;

implementation

{$R *.dfm}

procedure TFormObjects.FormCreate(Sender: TObject);
begin
  AnimationTime := 3; //defines animation duration regardless of range
  FNewTarget := GLCube1;
end;


function TFormObjects.GetCurveValue(Position: Single): Single;
begin
  Result := (1 + sin(DegToRad(270 + (Position * 180))))/2;
end;

procedure TFormObjects.GLSceneViewer1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  OldTarget.Position.AsAffineVector := dcTarget.Position.AsAffineVector;
  FNewTarget := GLSceneViewer1.Buffer.GetPickedObject(X,Y);
  StartTime := GLCadencer1.CurrentTime;
end;

procedure TFormObjects.GLCadencer1Progress(Sender: TObject; const deltaTime, newTime: Double);
var
  lCurveFactor: Single;
begin
  if newTime < StartTime + AnimationTime then
  begin
    lCurveFactor := GetCurveValue((newTime - StartTime)/AnimationTime);
    if assigned(FNewTarget) then
    begin
      dcTarget.Position.X := OldTarget.Position.X + lCurveFactor * (FNewTarget.Position.X - OldTarget.Position.X);
      dcTarget.Position.Y := OldTarget.Position.Y + lCurveFactor * (FNewTarget.Position.Y - OldTarget.Position.Y);
      dcTarget.Position.Z := OldTarget.Position.Z + lCurveFactor * (FNewTarget.Position.Z - OldTarget.Position.Z);
    end;
  end;
end;

end.
